﻿namespace Extensions.Web.ViewModel.Code
{
    using System;
    using System.ComponentModel;
    using System.IO;
    using System.Reflection;
    using System.Text;
    using System.Threading;
    using System.Web;

    public class ViewModelMaker
    {
        private string _expression;
        private string codeFilePath;

        public ViewModelMaker(string expression, string virtualPath)
        {
            this._expression = expression;
            this.codeFilePath = this.GetBuildCodeFilePath(virtualPath);
        }

        protected virtual void AddEventMethod(EventDescriptor eventDescriptor)
        {
            this.RidFileReadOnly();
            string str = File.ReadAllText(this.CodeFilePath);
            if (!str.Contains(" " + this.Expression + "("))
            {
                str = str.Remove(str.LastIndexOf("\r\n"));
                str = str.Remove(str.LastIndexOf("\r\n"));
                StringBuilder stringBuilder = new StringBuilder(str.Remove(str.LastIndexOf("\r\n")));
                stringBuilder.AppendLine();
                MethodInfo method = eventDescriptor.ComponentType.GetEvent(eventDescriptor.Name).EventHandlerType.GetMethod("Invoke");
                string str2 = (method.ReturnType.ToString() == "System.Void") ? "void" : method.ReturnType.ToString();
                string str3 = "";
                foreach (ParameterInfo info3 in method.GetParameters())
                {
                    string str4 = str3;
                    str3 = str4 + info3.ParameterType.ToString() + " " + info3.Name + ", ";
                }
                str3 = str3.TrimEnd(", ".ToCharArray());
                stringBuilder.AppendLine(2, "public virtual " + str2 + " " + this.Expression + "(" + str3 + ")");
                stringBuilder.AppendLine(2, "{");
                if (method.ReturnType.ToString() == "System.Void")
                {
                    stringBuilder.AppendLine();
                }
                else
                {
                    stringBuilder.AppendLine(3, "return default(" + method.ReturnType.ToString() + ");");
                }
                stringBuilder.AppendLine(2, "}");
                stringBuilder.AppendLine(1, "}");
                stringBuilder.AppendLine("}");
                File.WriteAllText(this.CodeFilePath, stringBuilder.ToString());
            }
        }

        internal void AddEventMethodWithTry(EventDescriptor eventDescriptor)
        {
            bool flag = true;
            while (flag)
            {
                try
                {
                    this.AddEventMethod(eventDescriptor);
                    flag = false;
                }
                catch (IOException)
                {
                    Thread.Sleep(1);
                }
            }
        }

        protected virtual void AddProperty(PropertyDescriptor propertyDescriptor)
        {
            this.RidFileReadOnly();
            string str = File.ReadAllText(this.CodeFilePath);
            if (!str.Contains("ViewState[\"" + this.Expression + "\"]"))
            {
                str = str.Remove(str.LastIndexOf("\r\n"));
                str = str.Remove(str.LastIndexOf("\r\n"));
                StringBuilder stringBuilder = new StringBuilder(str.Remove(str.LastIndexOf("\r\n")));
                stringBuilder.AppendLine();
                stringBuilder.AppendLine(2, "public virtual " + propertyDescriptor.PropertyType.ToString() + " " + this.Expression);
                stringBuilder.AppendLine(2, "{");
                stringBuilder.AppendLine(3, "get");
                stringBuilder.AppendLine(3, "{");
                stringBuilder.AppendLine(4, "return (ViewState[\"" + this.Expression + "\"] != null) ? (" + propertyDescriptor.PropertyType.ToString() + ")ViewState[\"" + this.Expression + "\"] : default(" + propertyDescriptor.PropertyType.ToString() + ");");
                stringBuilder.AppendLine(3, "}");
                stringBuilder.AppendLine(3, "set");
                stringBuilder.AppendLine(3, "{");
                stringBuilder.AppendLine(4, "ViewState[\"" + this.Expression + "\"] = value;");
                stringBuilder.AppendLine(3, "}");
                stringBuilder.AppendLine(2, "}");
                stringBuilder.AppendLine(1, "}");
                stringBuilder.AppendLine("}");
                File.WriteAllText(this.CodeFilePath, stringBuilder.ToString());
            }
        }

        protected virtual void AddProperty(string attributeName)
        {
            this.RidFileReadOnly();
            string str = File.ReadAllText(this.CodeFilePath);
            if (!str.Contains("ViewState[\"" + this.Expression + "\"]"))
            {
                str = str.Remove(str.LastIndexOf("\r\n"));
                str = str.Remove(str.LastIndexOf("\r\n"));
                StringBuilder stringBuilder = new StringBuilder(str.Remove(str.LastIndexOf("\r\n")));
                stringBuilder.AppendLine();
                stringBuilder.AppendLine(2, "public virtual System.String " + this.Expression);
                stringBuilder.AppendLine(2, "{");
                stringBuilder.AppendLine(3, "get");
                stringBuilder.AppendLine(3, "{");
                stringBuilder.AppendLine(4, "return (ViewState[\"" + this.Expression + "\"] != null) ? (System.String)ViewState[\"" + this.Expression + "\"] : default(System.String);");
                stringBuilder.AppendLine(3, "}");
                stringBuilder.AppendLine(3, "set");
                stringBuilder.AppendLine(3, "{");
                stringBuilder.AppendLine(4, "ViewState[\"" + this.Expression + "\"] = value;");
                stringBuilder.AppendLine(3, "}");
                stringBuilder.AppendLine(2, "}");
                stringBuilder.AppendLine(1, "}");
                stringBuilder.AppendLine("}");
                File.WriteAllText(this.CodeFilePath, stringBuilder.ToString());
            }
        }

        internal void AddPropertyWithTry(PropertyDescriptor propertyDescriptor)
        {
            bool flag = true;
            while (flag)
            {
                try
                {
                    this.AddProperty(propertyDescriptor);
                    flag = false;
                }
                catch (IOException)
                {
                    Thread.Sleep(1);
                }
            }
        }

        internal void AddPropertyWithTry(string attributeName)
        {
            bool flag = true;
            while (flag)
            {
                try
                {
                    this.AddProperty(attributeName);
                    flag = false;
                }
                catch (IOException)
                {
                    Thread.Sleep(1);
                }
            }
        }

        protected virtual void BuildBlankCode(string file, string className)
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.AppendLine("using System;");
            stringBuilder.AppendLine("using System.Collections.Generic;");
            stringBuilder.AppendLine("using System.Linq;");
            stringBuilder.AppendLine("using System.Web;");
            stringBuilder.AppendLine("using System.Web.UI;");
            stringBuilder.AppendLine("using System.Web.UI.WebControls;");
            stringBuilder.AppendLine();
            stringBuilder.AppendLine("namespace ViewModel.Base");
            stringBuilder.AppendLine("{");
            stringBuilder.AppendLine(1, "public abstract class " + className + " : Extensions.Web.UI.UserControl");
            stringBuilder.AppendLine(1, "{");
            stringBuilder.AppendLine(1, "}");
            stringBuilder.AppendLine("}");
            File.WriteAllText(file, stringBuilder.ToString());
        }

        private string GetBuildCodeFilePath(string virtualPath)
        {
            string className = virtualPath.Substring(HttpRuntime.AppDomainAppVirtualPath.Length).Replace("/", "_");
            className = className.Remove(className.LastIndexOf(".")).TrimStart(new char[] { '_' });
            string str2 = className + ".cs";
            string path = HttpRuntime.AppDomainAppPath.Replace(@"\", "/") + "App_Code/ViewModel/Base/";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            path = path + str2;
            if (!File.Exists(path))
            {
                this.BuildBlankCode(path, className);
                return path;
            }
            if (File.GetLastWriteTime(HttpRuntime.AppDomainAppPath.Replace(@"\", "/") + virtualPath.Substring(HttpRuntime.AppDomainAppVirtualPath.Length)) > File.GetLastWriteTime(path))
            {
                File.Delete(path);
                this.BuildBlankCode(path, className);
            }
            return path;
        }

        protected void RidFileReadOnly()
        {
            FileInfo info = new FileInfo(this.CodeFilePath);
            if (info.IsReadOnly)
            {
                info.IsReadOnly = false;
            }
        }

        protected string CodeFilePath
        {
            get
            {
                return this.codeFilePath;
            }
        }

        protected string Expression
        {
            get
            {
                return this._expression;
            }
        }
    }
}

